﻿using QQMusic.Helper;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

namespace QQMusic.Controls
{
    /// <summary>
    /// Carousel.xaml 的交互逻辑
    /// </summary>
    public partial class Carousel : UserControl
    {
        #region 属性
        private readonly List<RadioButton> radiobuttons = new List<RadioButton>()
        {
            new RadioButton(),
        };

        private readonly List<Storyboard> storyboards = new List<Storyboard>()
        {
            new Storyboard(),
        };

        private readonly List<Image> images = new List<Image>()
        {
            new Image(),
        };

        private int index = 0;

        private int select = 0;

        private int count = 0;

        public static readonly DependencyProperty DisplayHeightProperty =
            DependencyProperty.Register("DisplayHeight", typeof(double), typeof(Carousel), new PropertyMetadata(800.0));

        public double DisplayHeight
        {
            get => (double)GetValue(DisplayHeightProperty);
            set { SetValue(DisplayHeightProperty, value); }
        }

        public static readonly DependencyProperty DisplayWidthProperty =
            DependencyProperty.Register("DisplayWidth", typeof(double), typeof(Carousel), new PropertyMetadata(160.0));

        public double DisplayWidth
        {
            get => (double)GetValue(DisplayWidthProperty);
            set { SetValue(DisplayWidthProperty, value); }
        }

        public static readonly DependencyProperty ImagesProperty =
            DependencyProperty.Register("Images", typeof(List<string>), typeof(Carousel), new PropertyMetadata(null));

        public List<string> Images
        {
            get { return (List<string>)GetValue(ImagesProperty); }
            set { SetValue(ImagesProperty, value); }
        }
        #endregion

        private DispatcherTimer timer;

        public Carousel()
        {
            InitializeComponent();

            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(10);
            timer.Tick += Storyboard_Begin;
            timer.Start();
        }

        ~Carousel()
        {
            timer.Stop();
            timer.Tick -= Storyboard_Begin;
            timer = null;
        }

        private Storyboard StoryBoard(Image image, double val1, double val2, int seconds)
        {
            Storyboard storyboard = new Storyboard();
            var keyFrames = new DoubleAnimationUsingKeyFrames();
            var second = TimeSpan.FromMilliseconds(seconds);
            var keyFrame1 = new LinearDoubleKeyFrame(val1, KeyTime.FromTimeSpan(second));
            var keyFrame2 = new LinearDoubleKeyFrame(val2, KeyTime.FromTimeSpan(second));
            keyFrames.KeyFrames.Add(keyFrame1);
            keyFrames.KeyFrames.Add(keyFrame2);
            storyboard.Children.Add(keyFrames);
            Storyboard.SetTarget(keyFrames, image);
            Storyboard.SetTargetProperty(keyFrames, new PropertyPath("(Canvas.Left)"));
            storyboard.FillBehavior = FillBehavior.Stop;
            //storyboard.Completed += Storyboard_Begin;
            return storyboard;
        }

        private void Storyboard_Begin(object sender, EventArgs e)
        {
            if (Images?.Count > 0 && ImagesGrid.ActualWidth > 0)
            {
                timer.Interval = TimeSpan.FromMilliseconds(5000);
                count = ImagesGrid.ActualWidth > 1330 ? 3 : 2;
                DisplayWidth = ImagesGrid.ActualWidth / count - 20;
                DisplayHeight = ImagesGrid.ActualWidth / 5 + 10;
                ImageCanvas.Width = ImagesGrid.ActualWidth;
                ImageCanvas.Height = DisplayHeight;
                ImageCanvas.Children.Clear();
                RadioPanel.Children.Clear();
                OnSwitchImages(count, DisplayWidth, DisplayHeight);
            }
        }

        private void Storyboard_End()
        {
            for (int i = 0; i < storyboards.Count; i++)
            {
                storyboards[i].Stop();
                storyboards[i].Remove();
            }
        }

        private void OnSwitchImages(int count, double width = 345, double height = 160)
        {
            for (int i = 0; i < count; i++)
            {
                index %= Images.Count;
                double val = 10.0 + (i * (width + 20));
                if (images.Count <= i)
                    images.Add(new Image());

                images[i].Width = width;
                images[i].Height = height;
                images[i].Stretch = Stretch.Fill;
                images[i].Clip = new RectangleGeometry(new Rect(0, 0, width, height), 10.0, 10.0);
                images[i].SetValue(Canvas.TopProperty, 0.0);
                images[i].SetValue(Canvas.LeftProperty, val);
                ImageCanvas.Children.Add(images[i]);

                var bitmap = new BitmapImage();
                bitmap.BeginInit();
                bitmap.UriSource = new Uri(Images[index++], UriKind.RelativeOrAbsolute);
                bitmap.EndInit();
                images[i].Source = bitmap;

                if (storyboards.Count <= i)
                    storyboards.Add(new Storyboard());
                storyboards[i] = StoryBoard(images[i], val, val, 5000);
                storyboards[i].Begin();
            }
            int len = (Images.Count - Images.Count % count) / count + 1;
            string groupName = "ImagesGroup" + Guid.NewGuid().ToString("N");
            for (int i = 0; i < len; i++)
            {
                if (radiobuttons.Count <= i)
                    radiobuttons.Add(new RadioButton());
                radiobuttons[i].Margin = new Thickness(10.0);
                radiobuttons[i].GroupName = groupName;
                radiobuttons[i].Style = FindResource("BlackRadioButtonStyle") as Style;
                radiobuttons[i].IsChecked = (select % len) == i;
                RadioPanel.Children.Add(radiobuttons[i]);
            }
            select = (select + 1) % len;
        }

        private void Carousel_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            for (int i = 0; i < storyboards.Count; i++)
            {
                storyboards[i].Remove();
            }
            timer.Interval = TimeSpan.FromMilliseconds(10);
        }

        private void Carousel_MouseEnter(object sender, MouseEventArgs e)
        {
            List<Button> buttons = VisualHelper.GetChildList<Button>(this);
            foreach (Button button in buttons)
            {
                button.Visibility = Visibility.Visible;
            }
        }

        private void Carousel_MouseLeave(object sender, MouseEventArgs e)
        {
            List<Button> buttons = VisualHelper.GetChildList<Button>(this);
            foreach (Button button in buttons)
            {
                button.Visibility = Visibility.Hidden;
            }
        }

        private void Left_Button_Click(object sender, RoutedEventArgs e)
        {
            int len = (Images.Count - Images.Count % count) / count + 1;
            timer.Stop();
            Storyboard_End();
            int res = index - count * 2;
            index = res < 0 ? (Images.Count + res) : res;
            int ans = select - 2;
            select = ans < 0 ? len + ans : ans;
            timer.Interval = TimeSpan.FromMilliseconds(10);
            timer.Start();
        }

        private void Right_Button_Click(object sender, RoutedEventArgs e)
        {
            timer.Stop();
            Storyboard_End();
            timer.Interval = TimeSpan.FromMilliseconds(10);
            timer.Start();
        }
    }
}
